
#ifndef _ENNEMI_H_
#define _ENNEMI_H_

#include "Heros.h"


/** @brief File brief description
 Le fichier Ennemi.h contient la declaration de toutes les fonctions et procedures necessaires
à la gestion de n'importe lequel des ennemis d'un niveau (creation, deplacement, changements 
de ses caracteristiques a cause d'une action exterieure (par exemple perte de vie si touche
par un tir) et destruction*/


typedef enum {ennemi_faible, ennemi_fort, ennemi_moyen, asteroide} TypeEnnemi;

/** @brief La structure ennemi comporte le type de l'ennemi, ses points de vie (un entier), son abscisse et
 * son ordonnée (2 reels), sa taille suivant les 2 axes (2 reels), sa trajectoire) et des timer pour les tir et 
 * le deplacement*/
typedef struct 
{
	TypeEnnemi type_ennemi_std;
	int PV_ennemi;
	float posX_ennemi;
	float posY_ennemi;
	float tailleX_ennemi;
	float tailleY_ennemi;
	Trajectoire* ptraj_ennemi;
	int timer_deplacement_arrive;
	int timer_deplacement_base;
	int timer_deplacement;
	int timer_tir_base;
	int timer_tir;
} Ennemi;

/** @brief Cette procedure permet de choisir les caracteristiques d'un ennemi en lui fournissant des valeurs
 * en parametres, on définit ainsi son type, sa vie, sa position, sa taille et sa trajectoire
 * @param [in,out] pennemi
 * @param [in] type_ennemi
 * @param [in] posX
 * @param [in] posY
 * @param [in] ptraj*/
void initEnnemi (Ennemi* pennemi, const TypeEnnemi type_ennemi, const float posX, const float posY, Trajectoire* ptraj);

/** @brief Cette fonction  reserve dans le tas l'espace necessaire pour un ennemi,
 * l'initialise et retourne un pointeur sur l'ennemi créé
 * @param [in] type_ennemi
 * @param [in] posX
 * @param [in] posY
 * @param [in] ptraj
 * @return Ennemi* pennemi*/
Ennemi* creerEnnemi (const TypeEnnemi type_ennemi, const float posX, const float posY, Trajectoire* ptraj);

/** @brief Cette procedure libere l'espace memoire alloue dans le tas pour la trajectoire d'un ennemi
 * @param [in,out] pennemi*/
void libereEnnemi (Ennemi* pennemi);

/** @brief Cette procedure libere l'espace memoire alloue dans le tas pour un ennemi
 * @param [in,out] pennemi*/
void detruireEnnemi (Ennemi** ppennemi);

/** @brief Cette procedure permet de changer l'entier correspondant au timer du tir de l'ennemi 
 * (temps entre chaque tir)
 * @param [in,out] pennemi
 * @param [in] timer*/
void setTimerTir (Ennemi* pennemi, const int timer);

/** @brief Cette fonction permet de retourner un entier qui correspondant au timer du tir de l'ennemi 
 * (temps entre chaque tir)
 * @param [in] pennemi
 * @return pennemi->timer_tir*/
int getTimerTir (Ennemi* pennemi);

/** @brief Cette procedure permet de changer l'entier correspondant au timer du tir de base de l'ennemi 
 * (temps total entre chaque tir)
 * @param [in,out] pennemi
 * @param [in] timer*/
void setTimerTirBase (Ennemi* pennemi, const int timer);

/** @brief Cette fonction permet de changer l'entier correspondant au timer du tir de base de l'ennemi 
 * (temps total entre chaque tir)
 * @param [in] pennemi
 * @return pennemi->timer_tir_base*/
int getTimerTirBase (Ennemi* pennemi);

/** @brief Cette procedure permet de changer l'entier correspondant au timer d'arrivé de l'ennemi 
 * (temps d'arrivé avant son arret)
 * @param [in,out] pennemi
 * @param [in] timer*/
void setTimerDeplacementArrive (Ennemi* pennemi, const int timer);

/** @brief Cette fonction permet de retourner un entier qui correspondant au timer d'arrivé de l'ennemi 
 * (temps d'arrivéavant deplacement)
 * @param [in] pennemi
 * @return pennemi->timer_deplacement_arrive*/
int getTimerDeplacementArrive (Ennemi* pennemi);

/** @brief Cette procedure permet de changer l'entier correspondant au timer du deplacement de l'ennemi 
 * (temps avant deplacement)
 * @param [in,out] pennemi
 * @param [in] timer*/
void setTimerDeplacement (Ennemi* pennemi, const int timer);

/** @brief Cette fonction permet de retourner un entier qui correspondant au timer du deplacement de l'ennemi 
 * (temps avant deplacement)
 * @param [in] pennemi
 * @return pennemi->timer_deplacement*/
int getTimerDeplacement (Ennemi* pennemi);

/** @brief Cette procedure permet de changer l'entier correspondant au timer du deplacement de base de l'ennemi 
 * (temps total avant deplacement)
 * @param [in,out] pennemi
 * @param [in] timer*/
void setTimerDeplacementBase (Ennemi* pennemi, const int timer);

/** @brief Cette fonction permet de retourner l'entier correspondant au timer du deplacement de base de l'ennemi 
 * (temps total avant deplacement)
 * @param [in] pennemi
 * @return pennemi->timer_deplacement_base*/
int getTimerDeplacementBase (Ennemi* pennemi);

/** @brief Cette fonction retourne un entier correspondant au type de l'ennemi passe en parametre
 * @param [in] pennemi*/
const TypeEnnemi getTypeEnnemiStd (const Ennemi* pennemi);

/** @brief Cette procedure permet de changer le type d'un ennemi passe en parametre en fournissant
 * une nouvelle valeur en donnee
 * @param [in,out] pennemi
 * @param [in] type_ennemi*/
void setTypeEnnemiStd (Ennemi* pennemi, const TypeEnnemi type_ennemi);

/** @brief Cette fonction retourne un entier correspondant aux points de vie restants 
 * de l'ennemi passe en parametre
 * @param [in] pennemi
 * @return pennemi->PV_ennemi*/
const int getPvEnnemi (const Ennemi* pennemi);

/** @brief Cette procedure permet de changer la vie d'un ennemi passe en parametre en fournissant
 * une nouvelle valeur en donnee
 * @param [in,out] pennemi
 * @param [in] PV*/
void setPvEnnemi (Ennemi* pennemi, const int PV);

/** @brief Cette fonction retourne l'abscisse de l'ennemi passe en parametre
 * @param [in] pennemi
 * @return pennemi_>posX_ennemi*/
const float getPosXEnnemi (const Ennemi* ennemi);

/** @brief Cette procedure permet de changer l'abscisse d'un ennemi passe en parametre en fournissant
 * une nouvelle valeur en donnee
 * @param [in,out] pennemi
 * @param [in] posX*/
void setPosXEnnemi (Ennemi* pennemi, const float posX);

/** @brief Cette fonction retourne l'ordonnee de l'ennemi passe en parametre
 * @param [in] pennemi
 * @return pennemi->posY_ennemi*/
const float getPosYEnnemi (const Ennemi* pennemi);

/** @brief Cette procedure permet de changer l'ordonnee d'un ennemi passe en parametre en fournissant
 * une nouvelle valeur en donnee
 * @param [in,out] pennemi
 * @param [in] posY*/
void setPosYEnnemi (Ennemi* pennemi, const float posY);

/** @brief Cette fonction retourne la taille suivant l'axe des abscisse 
 * de l'ennemi passe en parametre
 * @param [in] pennemi
 * @return pennemi->tailleX_ennemi*/
const float getTailleXEnnemi (const Ennemi* pennemi);

/** @brief Cette procedure permet de changer la taille suivant l'axe des abscisses
 * d'un ennemi passe en parametre en fournissant une nouvelle valeur en donnee
 * @param [in,out] pennemi
 * @param [in] tailleX*/
void setTailleXEnnemi (Ennemi* pennemi, const float tailleX);

/** @brief Cette fonction retourne la taille suivant l'axe des ordonnees 
 * de l'ennemi passe en parametre
 * @param [in] pennemi
 * @return pennemi->tailleY_ennemi*/
const float getTailleYEnnemi (const Ennemi* pennemi);

/** @brief Cette procedure permet de changer la taille suivant l'axe des ordonnees
 * d'un ennemi passe en parametre en fournissant une nouvelle valeur en donnee
 * @param [in,out] pennemi
 * @param [in] tailleY*/
void setTailleYEnnemi (Ennemi* pennemi, const float tailleY);

/** @brief Cette procedure assure le deplacement d'un ennemi en verifiant a chaque fois
 * la validite des positions
 * @param [in,out] pennemi
 * @param [in] pterrain*/
void deplacerEnnemi (Ennemi* pennemi, Terrain* pterrain, float defil);

/** @brief Cette fonction cree un tir dirige depuis la position de l'ennemi passe en parametre 
 * vers le heros et retourne un pointeur sur ce tir
 * @param [in] pennemi
 * @param [in] pterrain
 * @param [in] pheros
 * @return ptir*/
Tir* tirerEnnemi (Ennemi* pennemi, Terrain* pterrain, Heros* pheros, float defil);

/** @brief Cette procedure diminue la vie de l'ennemi passe en parametre
 * @param [in,out] pennemi
 * @param [in] vie*/
void enleverVieEnnemi (Ennemi* pennemi, const int vie);

#endif
